package exception_0923;

import java.sql.SQLOutput;

/**
 * 异常：
 * 在java中，将程序执行过程中发生的一些不正常行为称之为“异常”，编译阶段语法错误不是异常！
 *
 * 两大最常见的异常
 * 1.越界异常
 * int[] data=new int[3];
 * System.out.println(data[3]);
 * 2.NPE(空指针异常，NullPointerException)
 * str=null;
 * System.out.println(str.length());
 *
 * 一切皆对象，异常也是类，每种异常都有相关的类来描述
 * 异常继承体系：
 * 所有异常的子类都 is a
 *
 * 两大异常：
 *1.Error:指的是Java虚拟机无法解决的严重问题，比如：JVM内部错误、资源耗尽
 *2.Exception:异常产生后程序员可以通过代码块进行处理，是程序继续执行
 *
 * 根据异常的发生时机又将异常分成两大类：
 * 1.非受查异常（运行时异常）：在程序运行时发生的异常，不需要显示进行异常处理的异常都是非受查异常。例如：Error与RunTimeException
 * 2.受查异常：在程序编译阶段需要显示进行异常处理的异常类。例如：IOException(IO相关的异常)，SQLException(数据库相关的异常)
 * try{
 *     //所有可能产生异常的代码块
 * }catch(要捕获的异常类型){
 *     //出现异常之后执行的代码
 * }finally{
 *     //无论是否产生异常，一定会执行的代码
 * }-可选代码块
 * //执行剩下的代码块
 * 一般资源关闭，网络关闭放到finally代码块中
 * finally包含return语句，则finally中的返回值会覆盖try和catch中的，finally只进行资源关闭操作不涉及返回值
 *
 * 如果多个catch代码块出现了父子关系，一定是子类写在前，父类写在后面。多个代码块只会捕捉一次，走一个catch程序代码块
 *
 * 异常处理流程：
 *
 * 1.方法内部产生异常，当前方法就处理
 * 2.方法内部产生异常，不处理异常，将异常对象沿着方法的调用链向上传递
 *
 * 两组关键字，和异常抛出有关
 * 1.throws用在方法声明上，明确表示当前方法可能产生的异常，但是当前方法不处理，将异常抛出给调用者（可以抛出多个异常）
 * throws抛出多个异常，如果有父子关系，只需要声明父类异常就行
 * 2.throw用在方法内部，表示人为进行异常对象的产生，一般和自定义异常搭配
 *
 * 自定义异常
 */
public class NormalException {//异常处理流程，没有进行异常处理，异常之后的代码都不在执行
    public static void main(String[] args) {
//        System.out.println("异常出现前");
//        try {
////            System.out.println(10/0);//程序在执行过程由于除以0出现异常
//            String str=null;
//            System.out.println(str.length());//NPE异常，此时捕捉不到异常，可以采取多个catch块
//        }catch (ArithmeticException e){//算数异常
//            System.err.println("异常产生了");
//            e.printStackTrace();
//        }catch(NullPointerException e){
//            System.err.println("异常产生了红色");//优先级低于标准输出
//            System.out.println("异常产生了黑色");
//            e.printStackTrace();//捕捉显示异常行数和信息
//        }
//
//        //也可以用父类Exception
//        try {
//            String str=null;
//            System.out.println(str.length());
//        }catch (Exception e){//不推荐，此时出现异常不知道具体地产生异常的原因
//            System.out.println("异常产生了");
//        }
//        System.out.println("异常发生之后！");
//    }
//    public static int fun(){//返回2
//        try{
//            return 1;
//        }finally {
//            return 2;
//        }

        //主方法处理异常，剩余代码正常执行
        try {
            fun();
        }catch (ArithmeticException e){//算数异常
            System.err.println("异常产生了");
            e.printStackTrace();
        }

        //主方法不处理异常,异常返回给JVM，结束代码(出现红字异常信息)
        fun();
    }

    public static void fun() throws ArithmeticException,NullPointerException,ClassCastException{
        //可以抛出多个异常，可以这几异常都不处理，抛出给调用者,也可以处理一个两个异常，其余抛出给调用者
        System.out.println(10/0);
        System.out.println("方法结束");
    }
}
